package controlador.AlgoHero;

import java.awt.Color;
import java.util.ArrayList;

import vista.AlgoHero.Puntuacion;
import vista.AlgoHero.VistaCola;
import vista.AlgoHero.VistaImagenLateral;
import vista.AlgoHero.VistaMangoGuitarra;
import vista.AlgoHero.VistaMarcadorPuntuaciones;
import vista.AlgoHero.VistaPrincipal;
import modelo.AlgoHero.Cancion;
import modelo.AlgoHero.ColaDeConjuntosReproducibles;
import modelo.AlgoHero.ConjuntoElementosReproducibles;
import modelo.AlgoHero.Constantes;
import modelo.AlgoHero.ImagenLateral;
import modelo.AlgoHero.MangoGuitarra;
import modelo.AlgoHero.MarcadorDePuntuaciones;
import modelo.AlgoHero.Reproductor;
import modelo.AlgoHero.Tecla;
import modelo.AlgoHero.Verificador;
import Titiritero.titiritero.*;
import Titiritero.titiritero.vista.TextoDinamico;

public class ControladorAlgoHero extends ControladorJuego {

	// private ControladorJuego controlador = null;
	private Reproductor reproductor;
	private ColaDeConjuntosReproducibles colaDeReproduccion;
	private MarcadorDePuntuaciones marcador;
	private ImagenLateral imagen;
	private ArrayList<Tecla> teclas;
	private Puntuacion puntuacion;

	public ControladorAlgoHero(SuperficieDeDibujo superficieDeDibujo,
			Cancion cancion) {

		super();
		MangoGuitarra unMango = new MangoGuitarra(Constantes.ANCHO_MANGO
				.getValor(), Constantes.ALTO_MANGO.getValor());
		unMango.setX(Constantes.POS_X_INICIAL_MANGO.getValor());

		colaDeReproduccion = new ColaDeConjuntosReproducibles();

		reproductor = new Reproductor(cancion, colaDeReproduccion);
		//reproductor.actualizarCola();

		teclas = new ArrayList<Tecla> ();
		
		// agrego las teclas que vamos a usar
		teclas.add(new Tecla('a'));
		teclas.add(new Tecla('s'));
		teclas.add(new Tecla('k'));
		teclas.add(new Tecla('l'));

		/*
		 * Luego instancio los objetos del framework: una ventana y el
		 * controlador
		 */
		// controlador = new ControladorJuego();
		this.setSuperficieDeDibujo(superficieDeDibujo);

		/*
		 * Instancio un cuadrado para que actue como vista de la mesa
		 */
		VistaMangoGuitarra vistaMango = new VistaMangoGuitarra();
		vistaMango.setPosicionable(unMango);

		/*
		 * Instancio una imagen para que actue como vista de la pelota
		 */
		VistaCola vistaElemento = new VistaCola();
		vistaElemento.setColaDeConjuntosReproducibles(this.colaDeReproduccion);
		vistaElemento.setPosicionable(this.colaDeReproduccion);

		this.marcador = new MarcadorDePuntuaciones();
		VistaMarcadorPuntuaciones vistaMarcador = new VistaMarcadorPuntuaciones(
				marcador);
		vistaMarcador.setPosicionable(marcador);
		
		puntuacion = new Puntuacion ();
		
		puntuacion.setMarcador(marcador);
		
		TextoDinamico textoPuntuacion = new TextoDinamico(puntuacion);
		
		textoPuntuacion.setPosicionable(puntuacion);
		
		textoPuntuacion.setColor(Color.BLACK);

		
		/*
		 * agrego la pelota a la lista de objetos vivios del controlador para
		 * que este le de vida dentro del gameloop
		 */
		this.agregarObjetoVivo(this.colaDeReproduccion);
		// controlador.agregarObjetoVivo(this);

		this.imagen = new ImagenLateral();

		VistaImagenLateral vistaImagen = new VistaImagenLateral();

		vistaImagen.setPosicionable(this.imagen);
		
		/*
		 * Agrego los objetos que actuan como vista a la lista de dibujables del
		 * controlador para que sean repintados al final de cada gameloop
		 */

		this.agregarDibujable(vistaMango);
		this.agregarDibujable(vistaElemento);
		this.agregarDibujable(vistaImagen);
		this.agregarDibujable(vistaMarcador);
		this.agregarDibujable(textoPuntuacion);
		
		/*
		 * finalmente establezco el intervalo de sleep dentro del gameloop y
		 * comienzo a ejecutar
		 */
		this.setIntervaloSimulacion(30);

	}

	public void comenzar() {
		this.comenzarJuegoAsyn();
		// comenzarJuego(10);
	}

	public void detener() {
		this.detenerJuego();
	}

	/**
	 * Le da comienzo al juego poniendo en marcha el gameloop.
	 * 
	 * @param cantidadDeCiclos
	 *            cantidad de ciclos que debe correr el gameloop..
	 */
	public void comenzarJuego(int cantidadDeCiclos) {
		int contador = 0;

		try {
			while (contador < cantidadDeCiclos) {
				this.simular();
				this.dibujar();
				Thread.sleep(10);
				contador++;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void comenzarJuego() {

		estaEnEjecucion = true;
		Verificador verificador = new Verificador();
		verificador.setPuntuacion(marcador);
		try {
			while (estaEnEjecucion) {			
				ConjuntoElementosReproducibles conjunto = null;
				if (this.colaDeReproduccion.size() >= this.colaDeReproduccion
						.getLONGITUD() - 1) {
					conjunto = this.colaDeReproduccion
					.getElem(0);
					verificador.setConjunto(conjunto);					
				}
				for (int i = 0; i <= Constantes.ALTO_NOTA_TOTAL.getValor()
						/ Constantes.CANTIDAD_DE_PIXELES_POR_MOVIMIENTO
								.getValor() - 1; i++) {
					verificador.verificarPresion(teclas);
					simular();
					dibujar();
					Thread.sleep(intervaloSimulacion);
				}
				this.reproductor.actualizarCola();
				if (this.colaDeReproduccion.estaVacia()) {

					estaEnEjecucion = false;
					this.detener();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void run() {
		this.comenzarJuego();
	}
	
	public void teclaApretada(char tecla) {
		// busco la tecla de la lista, le pongo isclicked = true
		changeStateTecla(true, tecla);
	}

	public void teclaSoltada(char tecla) {
		// busco la tecla de la lista, le pongo isclicked = false
		changeStateTecla(false, tecla);
	}

	public void changeStateTecla(boolean state, char teclaName) {
		for (int i = 0; i < teclas.size(); i++) {

			if (teclas.get(i).getNombre() == teclaName) {
				teclas.get(i).setIsClicked(state);
			}
		}
	}
}
